﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Skybot.Net.WebSockets.Sockets
{
    /// <summary>
    /// Socket客户端联接对像
    /// </summary>
    public class SocketClientConnection
    {
        /// <summary>
        /// 远程节点字符串表示形示
        /// </summary>
        public string RemoteEndPoint { get; set; }

        /// <summary>
        /// 异步操作节点
        /// </summary>
        internal System.Net.Sockets.SocketAsyncEventArgs AsyncEventArgs { get; set; }

        /// <summary>
        /// 客户端Socket对像
        /// </summary>
        public System.Net.Sockets.Socket Socket { get; set; }


        /// <summary>
        /// 接入时间
        /// </summary>
        public DateTime AcceptDateTime { get; set; }
        /// <summary>
        /// 用户数据
        /// </summary>
        internal object ConnUserToKen { get; set; }

        /// <summary>
        /// 用于外部使用的用户自定义数据
        /// </summary>
        public object UserToKen { get; set; }

        /// <summary>
        /// WebSocket Send 发送数据到客户端,打包服务器数据
        /// </summary>
        /// <param name="bytes">要发送的数据</param>
        /// <param name="sendMax">每次发送的最大数据包</param>
        /// <param name="sendDelegate">发送数据的委托,将提供打包好的数据,可直接用于其它Socket发送</param>
        public void Send(Byte[] bytes, int sendMax = 65536, Action<byte[]> sendDelegate = null)
        {
            bool canSend = true;
            //每次最大发送 64Kb的数据
            int SendMax = sendMax;

            int num = 0;
            //已经发送的字节数据
            int taked = 0;
            while (canSend)
            {
                //内容数据
                byte[] contentBytes = null;
                var sendArr = bytes.Skip(num * SendMax).Take(SendMax).ToArray();
                taked += sendArr.Length;
                if (sendArr.Length > 0)
                {
                    //是否可以继续发送
                    canSend = bytes.Length > taked;
                    if (sendArr.Length < 126)
                    {
                        #region 一次发送小于126的数据
                        contentBytes = new byte[sendArr.Length + 2];
                        contentBytes[0] = (byte)(num == 0 ? 0x81 : (!canSend ? 0x80 : 0));
                        contentBytes[1] = (byte)sendArr.Length;
                        Array.Copy(sendArr, 0, contentBytes, 2, sendArr.Length);
                        canSend = false;
                        #endregion

                    }
                    else if (sendArr.Length < 0xFFFF)
                    {
                        #region 发送小于65535的数据
                        contentBytes = new byte[sendArr.Length + 4];
                        //首次不分片发送,大于128字节的数据一次发完
                        if (!canSend && num == 0)
                        {
                            contentBytes[0] = 0x81;
                        }
                        else
                        {
                            //一个分片的消息由起始帧（FIN为0，opcode非0），若干（0个或多个）帧（FIN为0，opcode为0），结束帧（FIN为1，opcode为0）。
                            contentBytes[0] = (byte)(num == 0 ? 0x01 : (!canSend ? 0x80 : 0));
                        }
                        contentBytes[1] = 126;
                        byte[] ushortlen = BitConverter.GetBytes((short)sendArr.Length);
                        contentBytes[2] = ushortlen[1];
                        contentBytes[3] = ushortlen[0];
                        Array.Copy(sendArr, 0, contentBytes, 4, sendArr.Length);
                        #endregion
                    }
                    else if (sendArr.LongLength < long.MaxValue)
                    {
                        #region 一次发送所有数据
                        //long数据一次发完
                        contentBytes = new byte[sendArr.Length + 10];
                        //首次不分片发送,大于128字节的数据一次发完
                        if (!canSend && num == 0)
                        {
                            contentBytes[0] = 0x81;
                        }
                        else
                        {
                            //一个分片的消息由起始帧（FIN为0，opcode非0），若干（0个或多个）帧（FIN为0，opcode为0），结束帧（FIN为1，opcode为0）。
                            contentBytes[0] = (byte)(num == 0 ? 0x01 : (!canSend ? 0x80 : 0));
                        }
                        contentBytes[1] = 127;
                        byte[] ulonglen = BitConverter.GetBytes((long)sendArr.Length);
                        contentBytes[2] = ulonglen[7];
                        contentBytes[3] = ulonglen[6];
                        contentBytes[4] = ulonglen[5];
                        contentBytes[5] = ulonglen[4];
                        contentBytes[6] = ulonglen[3];
                        contentBytes[7] = ulonglen[2];
                        contentBytes[8] = ulonglen[1];
                        contentBytes[9] = ulonglen[0];

                        Array.Copy(sendArr, 0, contentBytes, 10, sendArr.Length);
                        #endregion
                    }
                }

                try
                {
                    if (contentBytes != null)
                    {
                        if (sendDelegate == null)
                        {
                            Socket.Send(contentBytes);
                        }
                        else
                        {
                            sendDelegate(contentBytes);
                        }

                    }

                }
                catch (NullReferenceException)
                {
                    break;
                }
                catch (System.Net.Sockets.SocketException)
                {

                    break;
                }
                catch (ObjectDisposedException)
                {
                    break;
                }
                finally
                {
                    num++;
                }


            }
        }
 

 

    }
}
